【C/C++】如何理解void*与int之间的类型转换 您所在的位置:网站首页 定义void *类型的指针 【C/C++】如何理解void*与int之间的类型转换

【C/C++】如何理解void*与int之间的类型转换

2023-08-15 10:51| 来源: 网络整理| 查看: 265

要理解void*和int之间地转换

首先理解int和int*之间的转换

一般我们将int*理解为存放着某个地址的指针,地址所指的内容是一个int类型的值。

如果我们将int*存放的内容通过*取出来,输出到屏幕上如下所示:

int main(){ int t = 10; int *p = &t; printf("%d\n",*p); return 0; }

在这里插入图片描述 而实际上,int*存的就是个地址而已,我们可以将地址打印出来:

int main(){ int t = 10; int *p = &t; long long tt = (long long)p; // 这里强行将int* 转为了int,(C中不要求显示,C++要求显示转换) printf("%x\n%x\n",tt,&t); return 0; }

在这里插入图片描述

int*存放的地址打印出来了:61fe0c。

在32位系统里,所有指针都是4个字节;64位系统里,所有指针都是8个字节。 而这里int*是8个字节的,转为long long也为8个字节所以不会丢失数据。

上面已经实现了将int*类型转为了long long int类型,也就是将地址以数据的形式存到了long long int中。

VICE VERSA.

将int类型转为int*类型,就是将int的数据存到了原本int*存放地址的位置。

int main(){ int t = 10; int *p = t; printf("%lld\n",p); return 0; }

在这里插入图片描述 这里我们将int型的数据转为了int*型,原本存放地址的指针直接存放了int型的值,在读出来的时候可以直接输出p而不需要*p,如果用了*p反而变成了去读10这个地址的内容,造成段错误。

这里同样报了warning,报的是没有显示进行转换,如果加上显示进行转换,会报类型大小不匹配也就是上面的错误,但是因为int*占8个字节,int占4个字节,所以不会丢失数据,故这里的warning也忽略。

将int和int*之间的转换延申到void*中

void* 可以理解为无类型指针,既然是无类型指针,不禁让人联想到泛型这个概念。

当确定了要使用int和void*转换,在实际使用中就将void*看作int*,保证类型大小不会丢失数据即可。

之所以我将它和泛型联系在一起,是因为void*出现在各种库函数和系统调用函数的接口参数中,而真正在使用这些函数的时候,我们传递的参数又是各种类型的,总是被显示或隐式地转换为void*。

比如:

void * memcpy(void *dest, const void *src, size_t len); void * memset ( void * buffer, int c, size_t num );

我们在使用的时候实际上进行了很多关于void*的隐式转换,void*在这些接口中更像是一个约束和规范,用来告诉我们这里可以传任意类型的指针。像上面这两个函数,我们就需要传指针或者数组就行了,因为这两个函数对指针参数的使用很明确。

应用场景

如果对指针参数的使用是 由我们自定义 的,那么传递void*就更单纯地只是一个约束,我们不一定非得传数组或者指针类型的数据,可以像上面那样传递int值强转为void*。

比如:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

这个是创建线程的函数,第三个参数是一个回调函数,第四个参数是回调函数的参数。

这里就属于对指针参数的使用是我们自定义的,那么就意味着我们传递void*参数的时候不一定要传数组或者指针,可以像上面例子那样往地址中存放int值传递过去,在我们自定义的回调函数里面直接从指针里取值即可,比如:

#include #include #include #include void * tfn(void * arg){ printf("%d\n",arg); return NULL; } int main(int argc, char * argv[]){ pthread_t tid; int i=10; int ret = pthread_create(&tid,NULL,tfn,(void*)i); if(ret !=0) fprintf(stderr,"pthread_create error: %s\n",strerror(ret)); pthread_exit(NULL); }

在这里插入图片描述 这是我遇到的int转void*的使用场景,且这样强转主要是要注意int和指针类型的大小会不会丢失数据。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有